package com.example.testdemo.progess_image;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;


/**
 * Created by MrYan on 2018/8/4.
 * 带下载进度条的ImageView
 */

@SuppressLint("AppCompatCustomView")
public class ProgressImgView extends ImageView {
    private Context context;
    public static final int HORIZONTAL = 0x01;//水平遮盖动画
    public static final int CIRCULAR_DIFFUSION = 0x02;//圆形扩散动画
    private int progressMode = HORIZONTAL;//进度条样式

    private Paint mPaint;
    private Paint textPaint;

    //记录进度
    private int progress;
    //记录进度计算出来到角度
    private int angle;
    //当前的角度
    private int atAngle;
    //是否为视频缩略图
    private boolean video;
    private int color = Color.parseColor("#66000000");//遮罩颜色
    private int proColor = Color.parseColor("#ffffff");//进度颜色

    private PorterDuffXfermode xfermode;

    private int diagonalLength;

    private RectF mRectF;//展示进度的区域;
    private boolean finishLoad;//加载完成；
    private float proOffset = 5;//变化系数（偏移量）可通过此参数调整速度 进度条动画速度的偏移量
    private float finishOffset = 10;// 完成后扩散动画的偏移量
    private RectF horizontalRectF;
    private int textSize;
    private Rect bounds;

    public ProgressImgView(Context context) {
        super(context);
        init(context);
    }

    public ProgressImgView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ProgressImgView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initRectF();
    }


    private void initRectF() {
        //根据宽高最小值，确认正圆进度条的区域

        horizontalRectF = new RectF(0, 0, getWidth(), getHeight());
        int www = Math.min(getWidth(), getHeight());
        int diameter = www / 2;
        int radius = diameter / 2;
        int left = getWidth() / 2 - radius;
        int top = getHeight() / 2 - radius;
        int right = getWidth() / 2 + radius;
        int bottom = getHeight() / 2 + radius;
        mRectF = new RectF(left, top, right, bottom);
        int squareEdgeA = getWidth() / 2;
        int squareEdgeB = getHeight() / 2;

        int aa = squareEdgeA * squareEdgeA;
        int bb = squareEdgeB * squareEdgeB;

        diagonalLength = (int) Math.sqrt(aa + bb);

        proOffset = 5;
        finishOffset = 10;
    }

    private void init(Context context) {
        this.context = context;
        mPaint = new Paint();
        mPaint.setColor(proColor);
        mPaint.setAntiAlias(true);
        xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setAntiAlias(true);
        textSize = 48;
        textPaint.setTextSize(textSize);
        textPaint.setTextAlign(Paint.Align.LEFT);
        bounds = new Rect();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int save = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
        if (progressMode == CIRCULAR_DIFFUSION) {
            circularDiffusionModeDraw(canvas);
            canvas.restoreToCount(save);
            computeAtAngle();
        }
        // MrYan 2018/8/22
        // 应需求，开发水平带文字的
        if (progressMode == HORIZONTAL && progress < 100) {
            horizontalRectF.left = getWidth() / 100 * progress;
            mPaint.setColor(color);
            canvas.drawRect(horizontalRectF, mPaint);
            String text = progress + "%";
            textPaint.getTextBounds(text, 0, text.length(), bounds);
            Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt();
            int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
            int x = getWidth() / 2 - bounds.width() / 2;
            Log.d("进度ImageView", "onDraw: 文字水平位置：" + x);
            //写进度
            canvas.drawText(text, x, baseline, textPaint);
            canvas.restoreToCount(save);
        }
    }

    /**
     * 绘制圆形扩散效果
     */
    private void circularDiffusionModeDraw(Canvas canvas) {
        mPaint.setColor(color);
        canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
        mPaint.setColor(proColor);
        mPaint.setXfermode(xfermode);
        if (!finishLoad) {
            canvas.drawArc(mRectF, -90f, atAngle, true, mPaint);
        } else {
            //偏移量递增，使动画越来越快
            finishOffset = finishOffset + 10;
            mRectF.left = mRectF.left - finishOffset;
            mRectF.top = mRectF.top - finishOffset;
            mRectF.right = mRectF.right + finishOffset;
            mRectF.bottom = mRectF.bottom + finishOffset;
            canvas.drawRoundRect(mRectF, getWidth(), getWidth(), mPaint);
            if ((mRectF.right - mRectF.left) / 2 > diagonalLength) {
                initRectF();
            } else {
                postInvalidate();
            }
        }
        mPaint.setXfermode(null);
    }


    public int getProgress() {
        return progress;
    }

    /**
     * 设置进度
     */
    public void setProgress(int progress) {
        finishLoad = false;
        this.progress = progress;
        if (progressMode == CIRCULAR_DIFFUSION) {
            this.angle = (int) (360f / 100f * progress);
            computeAtAngle();
        }
        if (progressMode == HORIZONTAL) {
            computeProgressPx();
        }
    }

    /**
     * 计算水平样式的像素
     */
    private void computeProgressPx() {

        postInvalidate();
    }

    /**
     * 计算动画应该执行的角度
     */
    private void computeAtAngle() {
        if (angle == 0) {
            atAngle = 0;
            postInvalidate();
            return;
        }
        if (atAngle < angle) {
            atAngle = atAngle + 5;
            postInvalidate();
            finishLoad = false;
        }
        if (atAngle == 360 && !finishLoad) {
            finishLoad = true;
            postInvalidate();
        }
    }

    /**
     * 是否是视频进度（保留方法，暂未实现）
     */
    public boolean isVideo() {
        return video;
    }

    /**
     * 设置视频进度（保留方法，暂未实现）
     */
    public void setVideo(boolean video) {
        this.video = video;
    }

    /**
     * 设置进度条样式
     *
     * @param progressMode
     */
    public void setProgressMode(int progressMode) {
        this.progressMode = progressMode;
    }
}
